package com.cheers.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.util.StringUtils;

import com.cheers.common.Constants;
import com.cheers.common.JPushUtil;
import com.cheers.dao.LuckEventDao;
import com.cheers.dao.ProductDao;
import com.cheers.model.ExchangeLuckEventLog;
import com.cheers.model.Lottery;
import com.cheers.model.LuckEvent;
import com.cheers.model.LuckEventCode;
import com.cheers.mvo.LuckEventJoinUser;
import com.cheers.mvo.LuckEventLog;
import com.cheers.mvo.MyCode;
import com.cheers.mvo.Winner;
import com.cheers.service.IntegralService;
import com.cheers.service.LuckEventService;

public class LuckEventServiceImpl extends AbstractServiceImpl implements LuckEventService {

	@Resource
	private LuckEventDao luckEventDao;
	@Resource
	private ProductDao productDao;
	@Resource
	private IntegralService integralService;
	

	@Override
	public void add(LuckEvent luckEvent) throws Exception {
		luckEventDao.save(luckEvent);
	}
	
	
	
	@Override
	public List<Map<String, Object>> recd() throws Exception {
		List<Map<String, Object>> result = null;
		List<LuckEvent> list = luckEventDao.recd();
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
//			String status = null;
			for (LuckEvent obj : list) {
				map = new HashMap<String, Object>();
				map.put("luckId", obj.getId());
				map.put("cgyId", obj.getCgyId());
				map.put("title", obj.getTitle());
				map.put("picture", getValue(obj.getPicture()));
//				map.put("price", String.format("%.2f", obj.getPrice()));
//				map.put("describe", getValue(obj.getDepict()));
//				map.put("buyed", String.valueOf(obj.getBuyed()));
//				map.put("total", String.valueOf(obj.getTotal()));
//				map.put("joins", String.valueOf(obj.getJoins()));
//				map.put("last", String.valueOf(obj.getTotal()-obj.getJoins()));
				map.put("phase", String.valueOf(obj.getPhase()));
				//活动类型
				map.put("type", "1");
				//0,上架  1,下架 2,抽奖结束
//				if (obj.getStatus() == 0) {
//					status = "进行中";
//				} else if (obj.getStatus() == 1) {
//					status = "抽奖中";
//				} else if (obj.getStatus() == 2) {
//					status = "抽奖结束";
//				}
//				map.put("status",status);
				map.put("ctime", sdf.format(obj.getCtime()));
				result.add(map);
			}
		}

		
//		List<Product> listProduct = productDao.recd();
//		if (list!=null && !list.isEmpty()) {
//			if (result == null) {
//				result = new ArrayList<Map<String, Object>>();
//			}
//			Map<String, Object> map = null;
//			for (Product p : listProduct) {
//				map = new HashMap<String, Object>();
//				map.put("productId", p.getId());
//				map.put("title", p.getTitle());
//				map.put("price", String.format("%.2f", p.getPrice()));
//				map.put("picture", getValue(p.getPicture()));
//				map.put("describe", getValue(p.getDepict()));
//				map.put("total", String.valueOf(p.getTotal()));
//				map.put("last", String.valueOf(p.getTotal()-p.getUses()));
//				map.put("buyed", String.valueOf(p.getBuyed()));
//				map.put("ctime", sdf.format(p.getCtime()));
//				//商品类型
//				map.put("type", "2");
//				result.add(map);
//			}
//		}
		
		return result;
	}

	@Override
	public void lottery() throws Exception {
		//获取数据
		String sql = "select * from lottery_info where status=0 order by ctime asc";
		List<Lottery> lotteryList = luckEventDao.findListBySql(Lottery.class, sql, null);
		
		//抽奖
		if (lotteryList!=null && !lotteryList.isEmpty()) {
			String[] winner = null;
			for (Lottery lottery : lotteryList) {
				//抽奖算法
				winner = winerByLottery(lottery.getLuckId());
				
				if (winner != null) {
					//设置获奖者ID
					lottery.setWinnerId(winner[0]);
					lottery.setWinCode(Integer.parseInt(winner[1]));
					lottery.setWinTime(new Date());
					//幸运活动下架
					lottery.setStatus(1);
					luckEventDao.save(lottery);
					
					LuckEvent luck = luckEventDao.get(LuckEvent.class, lottery.getLuckId());
					if (luck != null) {
						//抽奖结束
						luck.setStatus(2);
						luckEventDao.save(luck);
					}
					
					//推送参加与者
					push(luck.getId(), winner[0], luck.getCgyId(), String.valueOf(luck.getPhase()));
				}
			}
		}
	}
	
	/**
	 * 推送参加活动者
	 * @param eventId
	 * @param winnerId
	 * @param cgyId
	 * @param phase
	 */
	private void push(String eventId, String winnerId, String cgyId, String phase) {
		//获取参加活动人列表,唯一性
		List<String> list = null;
		try {
			list = luckEventDao.getEventJoinUser(eventId, winnerId);
		} catch (Exception e) {
			logger.error("获取活动参加人列表错误:"+eventId, e);
			return;
		}
		
		//推送消息
		String date = sdf.format(new Date());
		String content = "{\"type\":\"2\",\"time\":\""+date+"\",\"content\":\"contentValue\",\"ext\":{\"cgyId\":\""+cgyId+"\",\"phase\":\""+phase+"\"}}";
		//推送给获奖者
		JPushUtil.sendMessageWithAlias(winnerId, "", content.replace("contentValue", "你中奖啦"));
		//推送给参加者
		String joinContent = content.replace("contentValjue", "获奖名单");
		if (list!=null && !list.isEmpty()) {
			for (String userId : list) {
				JPushUtil.sendMessageWithAlias(userId, "", joinContent);
			}
		}
	}
	
	private String[] winerByLottery(String luckId) throws Exception {
		String[] result = null;
		
		LuckEvent luckEvent = luckEventDao.get(LuckEvent.class, luckId);
		if (luckEvent != null) {
			//生成幸运码
			int code = generateCode(luckEvent.getTotal());
			//检索获奖者
			result = getWinByCode(luckId, code);
		}
		return result;
	}
	
	private String[] getWinByCode(String luckId, int code) throws Exception {
		String[] result = null;
		
		Object[] obj = null;
		//等于幸运码
		obj = luckEventDao.getNear(luckId, code, 1);
		if (obj != null) {
			result = new String[2];
			result[0] = String.valueOf(obj[0]);
			result[1] = String.valueOf(obj[1]);
			return result;
		}
		
		//小于幸运码
		int low = 0;
		String lowUserId = null;
		obj = luckEventDao.getNear(luckId, code, 2);
		if (obj != null) {
			lowUserId = String.valueOf(obj[0]);
			low = Integer.parseInt(obj[1]+"");
		}
		
		//大于幸运码
		int high = 0;
		String highUserId = null;
		obj = luckEventDao.getNear(luckId, code, 3);
		if (obj != null) {
			highUserId = String.valueOf(obj[0]);
			high = Integer.parseInt(obj[1]+"");
		}
		
		//对比结果
		if (code-low == high-code) {
			result = new String[2];
			result[0] = highUserId;
			result[1] = String.valueOf(high);
		} else if (code-low > high-code) {
			if (!StringUtils.isEmpty(highUserId)) {
				result = new String[2];
				result[0] = highUserId;
				result[1] = String.valueOf(high);
			} else if (!StringUtils.isEmpty(lowUserId)) {
				result = new String[2];
				result[0] = lowUserId;
				result[1] = String.valueOf(low);
			}
		} else if (code-low < high-code) {
			if (!StringUtils.isEmpty(lowUserId)) {
				result = new String[2];
				result[0] = lowUserId;
				result[1] = String.valueOf(low);
			} else if (!StringUtils.isEmpty(highUserId)) {
				result = new String[2];
				result[0] = highUserId;
				result[1] = String.valueOf(high);
			}
		}
		return result;
	}

	@Override
	public int lastChance(String luckId) throws Exception {
		LuckEvent luck = luckEventDao.get(LuckEvent.class, luckId);
		if (luck != null) {
			return luck.getTotal()-luck.getJoins();
		}
		return 0;
	}

	@Override
	public List<Map<String, Object>> joinList(String luckId, int pageIndex,
			int pageSize) throws Exception {
		List<Map<String, Object>> result = null;
		List<LuckEventJoinUser> list = luckEventDao.joinListById(luckId, pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			for (LuckEventJoinUser obj : list) {
				map = new HashMap<String, Object>();
				//幸运活动参加者
				map.put("userId", obj.getUserId());
				map.put("username", obj.getUsername());
				//记录
				map.put("number", String.valueOf(obj.getNumber()));
				map.put("codes", obj.getCodes());
				map.put("ctime", obj.getCtime());
				result.add(map);
			}
		}
		return result;
	}

	@Override
	public String luck(String userId, String luckId, int num)
			throws Exception {
		logger.info("--- luck ---");
		//获取幸运活动
		LuckEvent luck = luckEventDao.get(LuckEvent.class, luckId);
		if (luck == null) {
			return null;
		}
		//是否已满
		if (luck.getTotal() <= luck.getJoins()) {
			return Constants.LUCK_FULL_CODE;
		}
		//获取用户总积分
		Long total = integralService.getTotalPoint(userId);
		if (total == null) {
			return Constants.POINT_TOTAL_CODE;
		}
		
		//剩余人次
		if (luck.getTotal()-luck.getJoins() < num) {
			return Constants.LUCK_NOT_CODE;
		}
		
		//对比是否可以兑换幸运活动
		int buyed = luck.getBuyed();
		int needPoint = buyed*num;
		if (needPoint > total) {
			return Constants.POINT_TOTAL_CODE;
		}
		
		//兑换商品,减少总积分
		String data = integralService.addPoint(userId, Constants.DECREASE_LUCK, -needPoint);
		if (data == null) {
			return Constants.USER_CODE;
		}
		
		//兑换幸运活动记录
		ExchangeLuckEventLog exLuckEventLog = new ExchangeLuckEventLog();
		exLuckEventLog.setUserId(userId);
		exLuckEventLog.setLuckId(luckId);
		exLuckEventLog.setPoint(needPoint);
		exLuckEventLog.setNum(num);
		exLuckEventLog.setCtime(new Date());
		luckEventDao.save(exLuckEventLog);
		
		//计算参加人数
		luck.setJoins(luck.getJoins() + num);
		if (luck.getTotal() <= luck.getJoins()) {
			luck.setStatus(1);
			luck.setOffTime(new Date());
		}
		luckEventDao.save(luck);
		
		//是否已满
		if (luck.getTotal() <= luck.getJoins()) {
			//放入准备抽奖状态
			Lottery lottery = new Lottery();
			lottery.setLuckId(luckId);
			lottery.setStatus(0);
			lottery.setCtime(new Date());
			luckEventDao.save(lottery);
		}
		
		// 返回幸运码
		StringBuffer result = new StringBuffer();
		int c = 0;
		for (int i=0; i<num; i++) {
			LuckEventCode code = new LuckEventCode();
			code.setUserId(userId);
			code.setLuckId(luckId);
			code.setLuckLogId(exLuckEventLog.getLogId());
			c = generateCode(luck.getTotal());
			code.setLuckCode(c);
			code.setCtime(new Date());
			luckEventDao.save(code);
			result.append(c).append(",");
		}
		result.deleteCharAt(result.length()-1);
		
//		return result.toString();
		return Constants.OK;
	}
	
	private int generateCode(int total) throws Exception {
		int result = 0;
		
		//随机数
		int random = (int)(Math.random()*total);
		
		//获取兑换记录
		List<Date> list = luckEventDao.listExchangeLog();
		int numTotal = 0;
		if (list!=null && !list.isEmpty()) {
			for (Date date : list) {
				numTotal += parse(date);
			}
		} else {
			//获取幸运活动
			list = luckEventDao.listLuckEvent();
			if (list!=null && !list.isEmpty()) {
				for (Date date : list) {
					numTotal += parse(date);
				}
			}
		}
		
		//与总人次取余
		int mod = numTotal%total;
		//余数加10000001 加随机数
		result = mod + 10000001 + random;
		return result;
	}
	
	private int parse(Date date) {
		int result = 0;
		StringBuffer sb = new StringBuffer();
		sb.append(date.getHours()).append(date.getMinutes()).append(date.getSeconds());
		result = Integer.parseInt(sb.toString());
		return result;
	}

	@Override
	public List<Map<String, Object>> find(String userId, String cgyId, int phase,
			int pageIndex, int pageSize) throws Exception {
		List<Map<String, Object>> result = null;
		List<LuckEventLog> list = luckEventDao.find(userId, cgyId, phase, pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			for (LuckEventLog obj : list) {
				map = new HashMap<String, Object>();
				//记录
				map.put("point", String.valueOf(obj.getPoint()));
				map.put("number", String.valueOf(obj.getNumber()));
				map.put("ctime", obj.getCtime());
				result.add(map);
			}
		}
		return result;
	}

	@Override
	public String phaseNum(String cgyId) throws Exception {
		return luckEventDao.phaseNum(cgyId);
	}

	@Override
	public List<Map<String, Object>> phaseList(String cgyId, int pageIndex,
			int pageSize) throws Exception {
		List<Map<String, Object>> result = null;
		List<LuckEvent> list = luckEventDao.phaseList(cgyId, pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			String status = null;
			for (LuckEvent obj : list) {
				map = new HashMap<String, Object>();
				map.put("luckId", obj.getId());
				map.put("cgyId", obj.getCgyId());
				map.put("title", obj.getTitle());
				map.put("price", String.format("%.2f", obj.getPrice()));
				map.put("picture", getValue(obj.getPicture()));
				map.put("describe", getValue(obj.getDepict()));
				map.put("buyed", String.valueOf(obj.getBuyed()));
				map.put("total", String.valueOf(obj.getTotal()));
				map.put("joins", String.valueOf(obj.getJoins()));
				map.put("last", String.valueOf(obj.getTotal()-obj.getJoins()));
				map.put("phase",String.valueOf(obj.getPhase()));
				//0,上架  1,下架 2,抽奖结束
				if (obj.getStatus() == 0) {
					status = "进行中";
				} else if (obj.getStatus() == 1) {
					status = "抽奖中";
				} else if (obj.getStatus() == 2) {
					status = "抽奖结束";
				}
				map.put("status",status);
				map.put("ctime", sdf.format(obj.getCtime()));
				result.add(map);
			}
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> phaseList(int pageIndex, int pageSize)
			throws Exception {
		List<Map<String, Object>> result = null;
		List<LuckEvent> list = luckEventDao.phaseList(pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			for (LuckEvent obj : list) {
				map = new HashMap<String, Object>();
				map.put("luckId", obj.getId());
				map.put("title", obj.getTitle());
				map.put("price", String.format("%.2f", obj.getPrice()));
				map.put("picture", getValue(obj.getPicture()));
				map.put("describe", getValue(obj.getDepict()));
				map.put("buyed", String.valueOf(obj.getBuyed()));
				map.put("total", String.valueOf(obj.getTotal()));
				map.put("joins", String.valueOf(obj.getJoins()));
				map.put("last", String.valueOf(obj.getTotal()-obj.getJoins()));
				map.put("phase",String.valueOf(obj.getPhase()));
				map.put("ctime", sdf.format(obj.getCtime()));
				result.add(map);
			}
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> list(int pageIndex, int pageSize)
			throws Exception {
		List<Map<String, Object>> result = null;
		List<LuckEvent> list = luckEventDao.list(pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			for (LuckEvent obj : list) {
				map = new HashMap<String, Object>();
				map.put("luckId", obj.getId());
				map.put("cgyId", obj.getCgyId());
				map.put("title", obj.getTitle());
				map.put("price", String.format("%.2f", obj.getPrice()));
				map.put("picture", getValue(obj.getPicture()));
				map.put("describe", getValue(obj.getDepict()));
				map.put("buyed", String.valueOf(obj.getBuyed()));
				map.put("total", String.valueOf(obj.getTotal()));
				map.put("joins", String.valueOf(obj.getJoins()));
				map.put("last", String.valueOf(obj.getTotal()-obj.getJoins()));
				map.put("phase",String.valueOf(obj.getPhase()));
				map.put("ctime", sdf.format(obj.getCtime()));
				result.add(map);
			}
		}
		return result;
	}
	
	@Override
	public List<Map<String, Object>> exchangeList(String userId, int pageIndex, int pageSize) throws Exception {
		List<Map<String, Object>> result = null;
		List<LuckEventLog> list = luckEventDao.exchangeList(userId, pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			String status = null;
			for (LuckEventLog obj : list) {
				map = new HashMap<String, Object>();
				//幸运活动
				map.put("luckId", obj.getLuckId());
				map.put("title", obj.getTitle());
				map.put("price", String.format("%.2f", Double.parseDouble(obj.getPrice())));
				map.put("picture", getValue(obj.getPicture()));
				map.put("describe", getValue(obj.getDescribe()));
				//0,上架  1,下架 2,抽奖结束
				if ("0".equals(obj.getStatus())) {
					status = "进行中";
				} else if ("1".equals(obj.getStatus())) {
					status = "抽奖中";
				} else if ("2".equals(obj.getStatus())) {
					status = "抽奖结束";
				}
				map.put("status",status);
				map.put("phase", getValue(obj.getPhase()));
				map.put("cgyId", getValue(obj.getCgyId()));
//				//记录
//				map.put("point", String.valueOf(obj.getPoint()));
//				map.put("number", String.valueOf(obj.getNumber()));
//				map.put("ctime", obj.getCtime());
				result.add(map);
			}
		}
		return result;
	}

	@Override
	public Map<String, String> load(String cgyId, int phase) throws Exception {
		Map<String, String> result = null;
		LuckEvent luck = luckEventDao.load(cgyId, phase);
		if (luck == null) {
			return result;
		}
		result = new HashMap<String, String>();
		result.put("luckId", luck.getId());
		result.put("cgyId", luck.getCgyId());
		result.put("title", luck.getTitle());
		result.put("price", String.format("%.2f", luck.getPrice()));
		result.put("picture", getValue(luck.getPicture()));
		result.put("describe", getValue(luck.getDepict()));
		result.put("buyed", String.valueOf(luck.getBuyed()));
		result.put("total", String.valueOf(luck.getTotal()));
		result.put("joins", String.valueOf(luck.getJoins()));
		result.put("last", String.valueOf(luck.getTotal()-luck.getJoins()));
		result.put("phase",String.valueOf(luck.getPhase()));
		//0,上架  1,下架 2,抽奖结束
		String status = null;
		if (luck.getStatus() == 0) {
			status = "进行中";
		} else if (luck.getStatus() == 1) {
			status = "抽奖中";
		} else if (luck.getStatus() == 2) {
			status = "抽奖结束";
		}
		result.put("status",status);
		result.put("ctime", sdf.format(luck.getCtime()));
		return result;
	}

	@Override
	public Map<String, Object> load(String luckId) throws Exception {
		Map<String, Object> result = null;
		LuckEvent luck = luckEventDao.get(LuckEvent.class, luckId);
		if (!StringUtils.isEmpty(luck)) {
			result = new HashMap<String, Object>();
			result.put("luckId", luck.getId());
			result.put("cgyId", luck.getCgyId());
			result.put("title", luck.getTitle());
			result.put("price", String.format("%.2f", luck.getPrice()));
			result.put("picture", getValue(luck.getPicture()));
			result.put("describe", getValue(luck.getDepict()));
			result.put("buyed", String.valueOf(luck.getBuyed()));
			result.put("total", String.valueOf(luck.getTotal()));
			result.put("joins", String.valueOf(luck.getJoins()));
			result.put("last", String.valueOf(luck.getTotal()-luck.getJoins()));
			result.put("phase",String.valueOf(luck.getPhase()));
			//0,上架  1,下架 2,抽奖结束
			String status = null;
			if (luck.getStatus() == 0) {
				status = "进行中";
			} else if (luck.getStatus() == 1) {
				status = "抽奖中";
			} else if (luck.getStatus() == 2) {
				status = "抽奖结束";
			}
			result.put("status",status);
			result.put("ctime", sdf.format(luck.getCtime()));
		}
		return result;
	}

	@Override
	public Map<String, Object> winner(String luckId) throws Exception {
		Map<String, Object> result = null;
		Winner winner = luckEventDao.winner(luckId);
		if (!StringUtils.isEmpty(winner)) {
			result = new HashMap<String, Object>();
			//获奖者
			result.put("userId", winner.getUserId());
			result.put("username", winner.getUsername());
			//幸运活动
			result.put("luckId", winner.getLuckId());
			result.put("title", winner.getTitle());
			result.put("picture", winner.getPicture());
			//记录
			result.put("code", winner.getCode());
			result.put("ctime", winner.getCtime());
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> codeList(String userId, int pageIndex,
			int pageSize) throws Exception {
		List<Map<String, Object>> result = null;
		List<MyCode> list = luckEventDao.codeList(userId, pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			for (MyCode obj : list) {
				map = new HashMap<String, Object>();
				//幸运活动
				map.put("luckId", obj.getLuckId());
				map.put("title", obj.getTitle());
				map.put("price", String.format("%.2f", Double.parseDouble(obj.getPrice())));
				map.put("picture", obj.getPicture());
				//记录
				map.put("code", obj.getCode());
				map.put("ctime", obj.getCtime());
				result.add(map);
			}
		}
		return result;
	}

	@Override
	public List<Map<String, Object>> winnerList(int pageIndex, int pageSize)
			throws Exception {
		List<Map<String, Object>> result = null;
		List<Winner> list = luckEventDao.winnerList(pageIndex*pageSize, pageSize);
		if (list!=null && !list.isEmpty()) {
			result = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			for (Winner obj : list) {
				map = new HashMap<String, Object>();
				//获奖者
				map.put("userId", obj.getUserId());
				map.put("username", obj.getUsername());
				//幸运活动
				map.put("luckId", obj.getLuckId());
				map.put("title", obj.getTitle());
				map.put("picture", obj.getPicture());
				//记录
				map.put("code", obj.getCode());
				map.put("ctime", obj.getCtime());
				result.add(map);
			}
		}
		return result;
	}
	
}
